﻿using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.IO;

public static class QMath //helper method class for ease of use
{
    static Random random = new Random();
    /// <summary>
    /// Calculate dx(movement X) from speed and direction
    /// </summary>
    public static float get_dx(float speed, float direction)
    {
        return speed * (float)Math.Cos(direction);
    }

    /// <summary>
    /// Calculate dy(movement Y) from speed and direction
    /// </summary>
    public static float get_dy(float speed, float direction)
    {
        return speed * (float)Math.Sin(direction);
    }


    /// <summary>
    /// Returns random number betwen MIN and MAX as int
    /// </summary>
    public static int RandomNumberInt(int min, int max)
    {
        return random.Next(min, max);
    }


    /// <summary>
    /// Returns random value from -PI to + PI
    /// </summary>
    public static float RandomDirection()
    {
        float a = random.Next(-3141, 3141);
        return a / 1000;
    }

    /// <summary>
    /// Returns random number betwen MIN and MAX as float /1000
    /// </summary>
    public static float RandomNumberFloatSmall(int min, int max)
    {
        float a = random.Next(min, max);
        return a / 1000;
    }

    /// <summary>
    /// Returns random number betwen MIN and MAX as float
    /// </summary>
    public static float RandomNumberFloat(int min, int max)
    {
        float a = random.Next(min, max);
        return a;
    }
    
    /// <summary>
    /// Angle from point one Vector2 to another Vector2
    /// </summary>
    public static double V2ToAngle1(Vector2 vec1, Vector2 vec2)
    {
        return Math.Atan2(vec2.Y - vec1.Y, vec2.X - vec1.X);
    }

    /// <summary>
    /// Moves one float closer to another float by specific other float
    /// </summary>
    public static float Interpolate(float fraction, float startingValue, float endingValue)
    {
        //startValu + (delta * fraction)
        return startingValue + ((endingValue - startingValue) * fraction);
    }

    /// <summary>
    /// Calculates position of specific Rectangle corner
    /// expl: top right = "x2 y1"
    /// </summary>
    public static Vector2 GetPointCord(Rectangle REC, string xy)
    {
        if (xy == "x1 y1") return new Vector2((float)REC.X, (float)REC.Y);
        if (xy == "x1 y2") return new Vector2((float)REC.X, (float)REC.Y + (float)REC.Height);
        if (xy == "x2 y1") return new Vector2((float)REC.X + (float)REC.Width, (float)REC.Y);
        if (xy == "x2 y2") return new Vector2((float)REC.X, (float)REC.Y + (float)REC.Height);

        return Vector2.Zero;
    }

    /// <summary>
    /// Calculate how deap two rectangles intersect and return thous values
    /// if they dont intersect, then return empty Vector2.
    /// </summary>
    public static Vector2 GetIntersectionDepth(this Rectangle rectA, Rectangle rectB)
    {
        //Rectangle puse izmēra
        float halfWidthA = rectA.Width / 2.0f;
        float halfHeightA = rectA.Height / 2.0f;
        float halfWidthB = rectB.Width / 2.0f;
        float halfHeightB = rectB.Height / 2.0f;

        // Rectangle centrs
        Vector2 centerA = new Vector2(rectA.Left + halfWidthA, rectA.Top + halfHeightA);
        Vector2 centerB = new Vector2(rectB.Left + halfWidthB, rectB.Top + halfHeightB);

        // Calculate current and minimum-non-intersecting distances between centers.
        float distanceX = centerA.X - centerB.X;
        float distanceY = centerA.Y - centerB.Y;
        float minDistanceX = halfWidthA + halfWidthB;
        float minDistanceY = halfHeightA + halfHeightB;

        // If we are not intersecting at all, return (0, 0).
        if (Math.Abs(distanceX) >= minDistanceX || Math.Abs(distanceY) >= minDistanceY)
            return Vector2.Zero;

        // Calculate and return intersection depths.
        float depthX = distanceX > 0 ? minDistanceX - distanceX : -minDistanceX - distanceX;
        float depthY = distanceY > 0 ? minDistanceY - distanceY : -minDistanceY - distanceY;
        return new Vector2(depthX, depthY);
    }

    /// <summary>
    /// Distance betwen centers of two Rectangles
    /// </summary>
    public static Vector2 GetDistance(this Rectangle rectA, Rectangle rectB)
    {
        // Calculate half sizes.
        float halfWidthA = rectA.Width / 2.0f;
        float halfHeightA = rectA.Height / 2.0f;
        float halfWidthB = rectB.Width / 2.0f;
        float halfHeightB = rectB.Height / 2.0f;

        // Calculate centers.
        Vector2 centerA = new Vector2(rectA.Left + halfWidthA, rectA.Top + halfHeightA);
        Vector2 centerB = new Vector2(rectB.Left + halfWidthB, rectB.Top + halfHeightB);

        // Calculate current distances between centers.
        float distanceX = centerA.X - centerB.X;
        float distanceY = centerA.Y - centerB.Y;

        return new Vector2(distanceX, distanceY);
    }

    /// <summary>
    /// Calculate if 2 rectangle intersect
    /// </summary>
    public static bool IsRectangleIntersectingRectangle(this Rectangle rectA, Rectangle rectB)
    {
        //Rectangle puse izmēra
        float halfWidthA = rectA.Width / 2.0f;
        float halfHeightA = rectA.Height / 2.0f;
        float halfWidthB = rectB.Width / 2.0f;
        float halfHeightB = rectB.Height / 2.0f;

        // Rectangle centrs
        Vector2 centerA = new Vector2(rectA.Left + halfWidthA, rectA.Top + halfHeightA);
        Vector2 centerB = new Vector2(rectB.Left + halfWidthB, rectB.Top + halfHeightB);

        // Calculate current and minimum-non-intersecting distances between centers.
        float distanceX = centerA.X - centerB.X;
        float distanceY = centerA.Y - centerB.Y;
        float minDistanceX = halfWidthA + halfWidthB;
        float minDistanceY = halfHeightA + halfHeightB;

        // If we are not intersecting at all, return false.
        if (Math.Abs(distanceX) >= minDistanceX || Math.Abs(distanceY) >= minDistanceY)
            return false;
        return true;
    }

    /// <summary>
    /// Checks if point (Vector2) is inside Rectangle
    /// </summary>
    public static bool IsPointInRectangle(this Rectangle rect, Vector2 point)
    {
        if (rect.X < (int)point.X && rect.X + rect.Width > (int)point.X && rect.Y < (int)point.Y && rect.Y + rect.Height > (int)point.Y)
            return true;
        else
            return false;
    }

    /// <summary>
    /// Checks if point (int, int) is inside Rectangle
    /// </summary>
    public static bool IsPointInRectangle(this Rectangle rect, int posX, int posY)
    {
        if (rect.X < (int)posX && rect.X + rect.Width > (int)posX && rect.Y < (int)posY && rect.Y + rect.Height > (int)posY)
            return true;
        else
            return false;
    }

    /// <summary>
    /// Return Rectangle bottom center coordinates
    /// </summary>
    public static Vector2 GetBottomCenter(this Rectangle rect)
    {
        return new Vector2(rect.X + rect.Width / 2.0f, rect.Bottom);
    }

    /// <summary>
    /// Return Texture size as Rectangle
    /// </summary>
    public static Rectangle GetSourceRectangle(this Texture2D texture)
    {
        return new Rectangle(0, 0, texture.Width, texture.Height);
    }

    /// <summary>
    /// Return Rectangle center(or not?)
    /// </summary>
    public static Rectangle CenterRectangle(this Rectangle r, int x, int y)
    {
        return new Rectangle(x - r.Center.X, y - r.Center.Y, r.Width, r.Height);
    }



    public static int FilesInFolderXNB(string path) //find number of files in folder
    {
        int count = 0;
        if (!string.IsNullOrEmpty(path))
        {
            var extensions = new string[] { ".xnb" };
            try
            {
                count = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories).Length; // Will Retrieve count of all files in directry and sub directries
            }
            catch { Console.WriteLine("could not retrieve number of files in folder!"); }
        }
        return count;
    }
}
